/**
  ETFAna project, Anyang Normal University && IMP-CAS
  \class ETFOnlineCache
  \brief to store online events for all daqs and present matched event combination
  to online source for aligned-daq data analysis
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2024-06-25
  \date 2024-06-25 last modified
  \attention
  changelog
  <table>
  <tr>  <th>Date        <th>Author      <th>Description                    </tr>
  <tr>  <td>2024-06-25   <td>Asia Sun    <td>file created                  </tr>
  </table>

  \copyright Copyright (c) 2021-2024 Anyang Normal U. && IMP-CAS with LGPLv3 LICENSE
*/

#ifndef ETFOnlineCache_h
#define ETFOnlineCache_h

#include <climits>
#include <vector>
#include "online_shm.h"

using std::vector;

class ETFUnpacker;
class ETFDaqData;

/// stores the online data of the daq for the event index
class ETFOnlineCache{
public:
  ETFOnlineCache();
  virtual ~ETFOnlineCache();

  static const int CACHE_DEPTH = 10; ///< nof cached events
  struct online_daq_t{
    ETFUnpacker *upk;
    ETFDaqData *daq;
    int cache[CACHE_DEPTH][online_shm_pxi::MAX_LEN];
    unsigned idx[CACHE_DEPTH]; ///< event index
    
    int find(unsigned ii) const{ // find i that let idx[i] == ii
      if(UINT_MAX == ii) return -1;
      for(int i = 0; i < CACHE_DEPTH; i++) if(idx[i] == ii) return i;
      return -1;
    } // end member function find
  };

  /// load a number of events, then do matching within them
  /// after all matches are exhausted, clear the cache and reload
  /// \retval true if matched events found, or false
  bool GetOneEvent();
  virtual void AddDaq(ETFUnpacker *u, ETFDaqData *d);
  /// clear all daqs and data
  virtual void Clear(); ///< ususally between spills, to enhance daq alignments

  const vector<int> &MatchedId() const{ return fMatchedId; }
  const vector<online_daq_t *> &daqs() const{ return fDaqs; }
  int ndaq() const{ return fNDaq; }
  unsigned CntEv() const{ return fCntEv; }
  int loaded() const{ return fNLoaded; }

protected:
  vector<online_daq_t *> fDaqs;
  vector<int> fMatchedId; ///< id of the found matched indices
  int fNLoaded; ///< nof loaded events in the caches
  unsigned fIndex, fCntEv; ///< fIndex: index of the matched ev
  int fNDaq; ///< nof daqs
};

#endif
